

<!DOCTYPE html>
<html lang="zh-CN" color-mode=light>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>mysql - 唱跳rap</title>
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  <meta name="google" content="notranslate" />
  
  <meta name="description" content="mysql总结基础架构

连接器： 身份认证和权限相关...">
  <meta name="author" content="东子">
  <link rel="icon" href="/images/icons/icon-29.png" type="image/png" sizes="16x16">
  <link rel="icon" href="/images/icons/icon-29@2x.png" type="image/png" sizes="32x32">
  <link rel="apple-touch-icon" href="/images/icons/icon-1024.png" sizes="180x180">
  <meta rel="mask-icon" href="/images/icons/stun-logo.svg" color="#333333">
  
    <meta rel="msapplication-TileImage" content="/images/icons/icon-1024.png">
    <meta rel="msapplication-TileColor" content="#000000">
  

  
<link rel="stylesheet" href="/css/style.css">


  
    
<link rel="stylesheet" href="https://at.alicdn.com/t/font_1445822_p6ry5n7lrr.css">

  

  
    
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css">

  

  
    
      
        
        
<link rel="stylesheet" href="https://cdn.bootcss.com/highlight.js/9.18.1/styles/xcode.min.css" name="highlight-style" mode="light">

      
        
        
<link rel="stylesheet" href="https://cdn.bootcss.com/highlight.js/9.18.1/styles/solarized-dark.min.css" name="highlight-style" mode="dark">

      
  

  <script>
    var CONFIG = window.CONFIG || {};
    var ZHAOO = window.ZHAOO || {};
    CONFIG = {
      isHome: false,
      fancybox: true,
      pjax: false,
      loading: {
        gif: '',
        lottie: ''
      },
      lazyload: {
        enable: true,
        only_post: 'false',
        loading: {
          gif: '',
          lottie: ''
        }
      },
      donate: {
        enable: false,
        alipay: 'https://pic.izhaoo.com/alipay.jpg',
        wechat: 'https://pic.izhaoo.com/wechat.jpg'
      },
      galleries: {
        enable: false
      },
      fab: {
        enable: true,
        always_show: false
      },
      carrier: {
        enable: true
      },
      daovoice: {
        enable: false
      },
      preview: {
        background: {
          default: '',
          api: 'https://api.paugram.com/bing/'
        },
        motto: {
          default: '我在开了灯的床头下，想问问自己的心啊。',
          typing: true,
          api: 'https://v2.jinrishici.com/one.json',
          data_contents: '["data","content"]'
        },
      },
      qrcode: {
        enable: true,
        type: 'url',
        image: 'https://pic.izhaoo.com/weapp-code.jpg',
      },
      toc: {
        enable: true
      },
      scrollbar: {
        type: 'default'
      },
      notification: {
        enable: false,
        delay: 4500,
        list: '',
        page_white_list: '',
        page_black_list: ''
      },
      search: {
        enable: false,
        path: ''
      }
    }
  </script>

  

  

<meta name="generator" content="Hexo 6.3.0"></head>

<body class="lock-screen">
  <div class="loading" id="loading"></div>
  
    


  <nav class="navbar">
    <div class="left">
      
        <i class="iconfont iconhome j-navbar-back-home"></i>
      
      
        <i class="iconfont iconqrcode j-navbar-qrcode"></i>
      
      
        <i class="iconfont iconmoono" id="color-toggle" color-toggle="light"></i>
      
      
    </div>
    <div class="center">mysql</div>
    <div class="right">
      <i class="iconfont iconmenu j-navbar-menu"></i>
    </div>
    
      <div id="qrcode-navbar"></div>
    
  </nav>

  
  

<nav class="menu">
  <div class="menu-container">
    <div class="menu-close">
      <i class="iconfont iconbaseline-close-px"></i>
    </div>
    <ul class="menu-content"><li class="menu-item">
        <a href="/ " class="underline "> 首页</a>
      </li><li class="menu-item">
        <a href="/archives/ " class="underline "> 归档</a>
      </li><li class="menu-item">
        <a href="/categories/ " class="underline "> 分类</a>
      </li><li class="menu-item">
        <a href="/about/ " class="underline "> 关于</a>
      </li></ul>
    
      <div class="menu-copyright"><p>Powered by <a target="_blank" href="https://gitee.com/comebackearly">东子</a>  | 爷-青结~~</p></div>
    
  </div>
</nav>
  <main id="main">
  <div class="article-wrap">
    <div class="row container">
      <div class="col-xl-3"></div>
      <div class="col-xl-6"><article class="article">
  <div class="wrap">
    <section class="head">
  <img   class="lazyload" data-original="https://cdn.hackersandslackers.com/2018/04/mysql1.jpg" src=""  draggable="false">
  <div class="head-mask">
    <h1 class="head-title">mysql</h1>
    <div class="head-info">
      <span class="post-info-item"><i class="iconfont iconcalendar"></i>六月 03, 2022</span>
      
      <span class="post-info-item"><i class="iconfont iconfont-size"></i>9509</span>
    </div>
  </div>
</section>
    <section class="main">
      <section class="content">
        
        <h1 id="mysql总结"><a href="#mysql总结" class="headerlink" title="mysql总结"></a>mysql总结</h1><h2 id="基础架构"><a href="#基础架构" class="headerlink" title="基础架构"></a>基础架构</h2><p><img   class="lazyload" data-original="https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/13526879-3037b144ed09eb88.png" src=""  alt="img"></p>
<ul>
<li><strong>连接器：</strong> 身份认证和权限相关</li>
<li><strong>查询缓存：</strong> 执行查询语句的时候，会先查询缓存（MySQL 8.0 版本后移除，因为这个功能不太实用）。</li>
<li><strong>分析器：</strong> 分析器说白了就是要先看你的 SQL 语句要干嘛，再检查你的 SQL 语句语法是否正确。</li>
<li><strong>优化器：</strong> mysql 有自己的推荐，按照 MySQL 认为最优的方案去执行。</li>
<li><strong>执行器：</strong> 执行语句，然后从存储引擎返回数据。 </li>
<li><strong>插件式存储引擎</strong> ： 主要负责数据的存储和读取，采用的是插件式架构，支持 InnoDB、MyISAM、Memory 等多种存储引擎。</li>
</ul>
<h2 id="什么是三大范式"><a href="#什么是三大范式" class="headerlink" title="什么是三大范式"></a>什么是三大范式</h2><ul>
<li><strong>第一范式（1NF）</strong>：字段（或属性）是不可分割的最小单元，即不会有重复的列，体现原子性</li>
<li><strong>第二范式（2NF）</strong>：满足 1NF 前提下，存在一个候选码，非主属性全部依赖该候选码，即存在主键，体现唯一性，专业术语则是<strong>消除部分函数依赖</strong></li>
<li><strong>第三范式（3NF）</strong>：满足 2NF 前提下，非主属性必须互不依赖，<strong>消除传递依赖</strong></li>
</ul>
<h2 id="什么是范式和反范式，以及各自优缺点"><a href="#什么是范式和反范式，以及各自优缺点" class="headerlink" title="什么是范式和反范式，以及各自优缺点"></a>什么是范式和反范式，以及各自优缺点</h2><p><strong>范式</strong>是符合某一种级别的关系模式的集合。构造数据库必须遵循一定的规则。在关系数据库中，这种规则就是范式。</p>
<table>
<thead>
<tr>
<th>名称</th>
<th>优点</th>
<th>缺点</th>
</tr>
</thead>
<tbody><tr>
<td>反范式</td>
<td>反范式的过程就是通过冗余数据来提高查询性能，可以减少表关联和更好进行索引优化</td>
<td>存在大量冗余数据，并且数据的维护成本更高</td>
</tr>
<tr>
<td>范式</td>
<td>范式化的表减少了数据冗余，数据表更新操作快、占用存储空间少。</td>
<td>查询时通常需要多表关联查询，更难进行索引优化</td>
</tr>
</tbody></table>
<p>所以在平时工作中，我们通常是将范式和反范式相互结合使用。</p>
<h2 id="存储引擎"><a href="#存储引擎" class="headerlink" title="存储引擎"></a>存储引擎</h2><blockquote>
<p>通过 show engines；查看</p>
</blockquote>
<p>MySQL 5.5.5 之前，MyISAM 。之后，InnoDB 是 MySQL 的默认存储引擎。</p>
<h3 id="MySQL-存储引擎架构"><a href="#MySQL-存储引擎架构" class="headerlink" title="MySQL 存储引擎架构"></a>MySQL 存储引擎架构</h3><p>MySQL 存储引擎采用的是 <strong>插件式架构</strong> ，支持多种存储引擎，我们甚至可以为不同的数据库表设置不同的存储引擎以适应不同场景的需要。<strong>存储引擎是基于表的，而不是数据库。</strong></p>
<h3 id="MyISM-和InnoDB-有什么区别"><a href="#MyISM-和InnoDB-有什么区别" class="headerlink" title="MyISM 和InnoDB 有什么区别"></a>MyISM 和InnoDB 有什么区别</h3><p><img   class="lazyload" data-original="https://gitee.com/yuan-wendong/picture-bed/raw/master/image-20230308143459517.png" src=""  alt="image-20230308143459517">MyISAM 的性能还行，各种特性也还不错（比如<strong>全文索引、压缩、空间函数</strong>等)。但是，MyISAM <strong>不支持事务和行级锁</strong>，而且最大的缺陷就是崩溃后无法安全恢复。下面是一些主要的区别</p>
<ul>
<li><strong>行级锁</strong></li>
<li><strong>支持事务</strong></li>
<li><strong>外键</strong></li>
<li><strong>MVCC</strong>（InnorDB支持）</li>
</ul>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">InnoDB 支持行级别的锁粒度，MyISAM 不支持，只支持表级别的锁粒度。</span><br><span class="line">MyISAM 不提供事务支持。InnoDB 提供事务支持，实现了 SQL 标准定义了四个隔离级别。</span><br><span class="line">MyISAM 不支持外键，而 InnoDB 支持。</span><br><span class="line">MyISAM 不支持 MVVC，而 InnoDB 支持。</span><br><span class="line">虽然 MyISAM 引擎和 InnoDB 引擎都是使用 <span class="selector-tag">B</span>+Tree 作为索引结构，但是两者的实现方式不太一样。</span><br><span class="line">MyISAM 不支持数据库异常崩溃后的安全恢复，而 InnoDB 支持。</span><br></pre></td></tr></table></figure>

<h3 id="InnoDB-和-MyISAM-都支持-B-树索引，但是它们数据的存储结构实现方式不同。"><a href="#InnoDB-和-MyISAM-都支持-B-树索引，但是它们数据的存储结构实现方式不同。" class="headerlink" title="InnoDB 和 MyISAM 都支持 B+ 树索引，但是它们数据的存储结构实现方式不同。"></a>InnoDB 和 MyISAM 都支持 B+ 树索引，但是它们数据的存储结构实现方式不同。</h3><ul>
<li><strong>InnoDB</strong> 存储引擎：B+ 树索引的<strong>叶子节点保存数据本身</strong>；</li>
<li><strong>MyISAM</strong> 存储引擎：B+ 树索引的叶子节点保存<strong>数据的物理地址</strong>；</li>
</ul>
<h2 id="索引"><a href="#索引" class="headerlink" title="索引"></a>索引</h2><h3 id="什么是索引？"><a href="#什么是索引？" class="headerlink" title="什么是索引？"></a>什么是索引？</h3><p>索引的作用就相当于书的目录。打个比方: 我们在查字典的时候，如果没有目录，那我们就只能一页一页的去找我们需要查的那个字，速度很慢。如果有目录了，我们只需要先去目录里查找字的位置，然后直接翻到那一页就行了。</p>
<h3 id="索引的优缺点"><a href="#索引的优缺点" class="headerlink" title="索引的优缺点"></a>索引的优缺点</h3><ul>
<li>优点：</li>
</ul>
<p>​		使用索引可以大大<strong>加快</strong> 数据的检索<strong>速度</strong>（大大减少检索的数据量）</p>
<p>通过创建唯一性索引，可以保证数据库表中每一行数据的唯一性。</p>
<ul>
<li><p>缺点</p>
<p>创建索引和维护索引需要<strong>耗费许多时间</strong>。当对表中的数据进行<strong>增删改</strong>的时候，如果数据有索引，那么索引也需要动态的修改，会降低 SQL 执行效率。</p>
<p>索引需要使用物理文件存储，也会耗费一定空间。</p>
</li>
</ul>
<h3 id="索引底层数据结构-为什么-MySQL-没有使用其作为索引的数据结构呢？"><a href="#索引底层数据结构-为什么-MySQL-没有使用其作为索引的数据结构呢？" class="headerlink" title="索引底层数据结构,为什么 MySQL 没有使用其作为索引的数据结构呢？"></a>索引底层数据结构,<strong>为什么 MySQL 没有使用其作为索引的数据结构呢？</strong></h3><ul>
<li><p>Hash 表</p>
<p>哈希表可以快速检索数据（接近 O（1））</p>
<p>因为 Hash 索引不支持顺序和<strong>范围查询</strong>。并且，<strong>每次 IO 只能取一个</strong>。</p>
</li>
<li><p>B 树&amp; B+树</p>
<p>B 树也称 B-树,全称为 <strong>多路平衡查找树</strong> ，B+ 树是 B 树的一种变体。</p>
</li>
<li><p>全文索引：对文本的内容进行分词，进行搜索。目前只有 <code>CHAR</code>、<code>VARCHAR</code> ，<code>TEXT</code> 列上可以创建全文索引。<strong>ElasticSearch 代替</strong></p>
</li>
</ul>
<h3 id="B树，B-树的区别"><a href="#B树，B-树的区别" class="headerlink" title="B树，B+树的区别"></a>B树，B+树的区别</h3><ul>
<li>B 树的所有节点**既存放键(key) 也存放 数据(data)**，而 <strong>B+树只有叶子节点</strong>存放 key 和 data，其他内节点只存放 key。</li>
<li>B 树的叶子节点都是独立的;<strong>B+树的叶子节点有一条引用链指向与它相邻的叶子节点</strong>。</li>
<li>B 树的检索的过程相当于对范围内的每个节点的关键字做二分查找，可能还没有到达叶子节点，检索就结束了。而 B+树的<strong>检索效率就很稳定</strong>了，任何查找都是从根节点到叶子节点的过程，叶子节点的顺序检索很明显。</li>
</ul>
<blockquote>
<p>MyISAM 引擎和 InnoDB 引擎都是使用 B+Tree 作为索引结构，但是，两者的实现方式不太一样。</p>
</blockquote>
<h3 id="索引的分类"><a href="#索引的分类" class="headerlink" title="索引的分类"></a>索引的分类</h3><ul>
<li><strong>按照底层存储方式角度划分</strong>：</li>
</ul>
<p>​		聚簇索引（聚集索引）：<strong>索引结构和数据一起存放的索引</strong>，<strong>InnoDB</strong> <strong>中的主键索引</strong>就属于聚簇索引。指索引的键值的逻辑顺序与表中相应行的物理顺序一致，即每张表只能有一个聚簇索引，也就是我们常说的<strong>主键索引</strong>；</p>
<p>​		非聚簇索引（非聚集索引）：<strong>索引结构和数据分开存放的索引</strong>，二级索引(辅助索引)就属于非聚簇索引。MySQL 的 MyISAM 引擎，		不管主键还是非主键，使用的都是非聚簇索引。<strong>非聚簇索引</strong>的逻辑顺序则与数据行的物理顺序不一致。</p>
<ul>
<li><p><strong>按照应用维度划分：</strong></p>
<ul>
<li><p>主键索引：加速查询 + 列值唯一（不可以有 NULL）+ 表中只有一个。</p>
</li>
<li><p>普通索引：仅加速查询。</p>
</li>
<li><p>唯一索引：加速查询 + 列值唯一（可以有 NULL）。</p>
</li>
<li><p>覆盖索引：一个索引包含（或者说覆盖）所有需要查询的字段的值。</p>
</li>
<li><p>联合索引：多列值组成一个索引，专门用于组合搜索，其<strong>效率大于索引合并。</strong></p>
</li>
<li><p>全文索引：对文本的内容进行分词，进行搜索。目前只有 <code>CHAR</code>、<code>VARCHAR</code> ，<code>TEXT</code> 列上可以创建全文索引。一般不会使用，效率较低，通常使用搜索引擎如 ElasticSearch 代替。</p>
</li>
</ul>
</li>
</ul>
<h3 id="主键索引"><a href="#主键索引" class="headerlink" title="主键索引"></a>主键索引</h3><p>一张数据表有只能有一个主键，并且主键<strong>不能为 null，不能重复。</strong></p>
<p>在 MySQL 的 InnoDB 的表中，当没有显示的指定表的主键时，<strong>InnoDB 会自动先检查表中是否有唯一索引且不允许存在 null 值的字段，</strong>如果有，则选择该字段为默认的主键，否则 InnoDB 将会<strong>自动创建一个 6Byte 的自增主键。</strong></p>
<p><img   class="lazyload" data-original="https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/open-source-project/cluster-index.png" src=""  alt="img"></p>
<h3 id="二级索引-辅助索引"><a href="#二级索引-辅助索引" class="headerlink" title="二级索引(辅助索引)"></a>二级索引(辅助索引)</h3><p>二级索引又称为辅助索引，是因为二级索引的<strong>叶子节点存储的数据是主键</strong>。也就是说，通过二级索引，可以定位主键的位置。</p>
<p>唯一索引，普通索引，前缀索引等索引属于二级索引。</p>
<p><img   class="lazyload" data-original="https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/open-source-project/no-cluster-index.png" src=""  alt="img"></p>
<h3 id="聚簇索引与非聚簇索引，及其优缺点"><a href="#聚簇索引与非聚簇索引，及其优缺点" class="headerlink" title="聚簇索引与非聚簇索引，及其优缺点"></a>聚簇索引与非聚簇索引，及其优缺点</h3><p>聚簇索引即<strong>索引结构和数据一起存放</strong>的索引，并不是一种单独的索引类型。InnoDB 中的主键索引就属于聚簇索引。</p>
<p>非聚簇索引即索引<strong>结构和数据分开存放</strong>的索引，并不是一种单独的索引类型。二级索引(辅助索引)就属于非聚簇索引。MySQL 的 MyISAM 引擎，不管主键还是非主键，使用的都是非聚簇索引。</p>
<p><strong>非聚簇索引</strong></p>
<p>优：更新代价比聚簇索引要小 。非聚簇索引的更新代价就没有聚簇索引那么大了，非聚簇索引的叶子节点是不存放数据的</p>
<p>缺：</p>
<ul>
<li><strong>可能会二次查询(回表)</strong> ： 当查到索引对应的指针或主键后，可能还需要根据指针或主键再到数据文件或表中查询。</li>
</ul>
<h3 id="非聚簇索引一定回表查询吗"><a href="#非聚簇索引一定回表查询吗" class="headerlink" title="非聚簇索引一定回表查询吗?"></a>非聚簇索引一定回表查询吗?</h3><p>不是，如下这种情况 </p>
<figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="type">name</span> <span class="keyword">FROM</span> <span class="keyword">table</span> <span class="keyword">WHERE</span> <span class="type">name</span>=<span class="string">&#x27;guang19&#x27;</span>;</span><br></pre></td></tr></table></figure>

<p><strong>主键索引本身的 key 就是主键</strong>，查到返回就行了。这种情况就称之为<strong>覆盖索引</strong>了</p>
<h3 id="最左前缀匹配原则"><a href="#最左前缀匹配原则" class="headerlink" title="最左前缀匹配原则"></a>最左前缀匹配原则</h3><p>如建立 <code>(a,b,c,d)</code> 索引，查询条件 <code>b = 2</code> 是匹配不到索引的，但是如果查询条件是 <code>a = 1 and b = 2</code> 或 <code>a=1 </code>又或 <code>b = 2 and a = 1</code> 就可以，因为优化器会自动调整 a,b 的顺序。</p>
<p>再比如 <code>a = 1 and b = 2 and c &gt; 3 and d = 4</code>，其中 d 是用不到索引的，因为 c 是一个范围查询，它之后的字段会停止匹配。</p>
<p><strong>最左匹配的原理</strong></p>
<p><img   class="lazyload" data-original="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvNzUyOTcxLzIwMTkxMC83NTI5NzEtMjAxOTEwMTcyMTEzMDc3NzctMTA0NzgzNTQ1OS5wbmc" src=""  alt="img"></p>
<p>上图可以看出 a 是有顺序的（1、1、2、2、3、3），而 b 的值是没有顺序的（1、2、1、4、1、2）。所以 <code>b = 2</code> 这种查询条件无法利用索引。</p>
<p>同时我们还可以发现在 a 值相等的情况下（a &#x3D; 1），b 又是顺序排列的，所以最左匹配原则遇上范围查询就会停止，剩下的字段都无法使用索引。</p>
<h3 id="索引下推"><a href="#索引下推" class="headerlink" title="索引下推"></a>索引下推</h3><p><strong>索引下推</strong> 是 <strong>MySQL 5.6</strong> 版本中提供的一项索引优化功能，可以在非聚簇索引遍历过程中，对索引中包含的字段先做判断，过滤掉不符合条件的记录，减少回表次数</p>
<h3 id="使用索引的注意事项（设计原则）"><a href="#使用索引的注意事项（设计原则）" class="headerlink" title="使用索引的注意事项（设计原则）"></a>使用索引的注意事项（设计原则）</h3><ul>
<li><strong>字符串类型的字段使用前缀索引</strong>代替普通索引：前缀索引仅限于字符串类型，较普通索引会占用更小的空间，所以可以考虑使用前缀索引带替普通索引。</li>
</ul>
<blockquote>
<p>索引并不是越多越好，建议单张表索引不超过 5 个！索引可以提高效率同样可以降低效率。</p>
</blockquote>
<ul>
<li><p>避免索引失效</p>
</li>
<li><p>删除长期未使用的索引</p>
</li>
<li><p><strong>为常作为查询条件的字段建立索引</strong></p>
</li>
<li><p><strong>为经常需要排序、分组和联合操作的字段建立索引</strong>；</p>
</li>
<li><p><strong>限制索引的数目</strong>；</p>
</li>
</ul>
<h3 id="索引失效的原因"><a href="#索引失效的原因" class="headerlink" title="索引失效的原因"></a>索引失效的原因</h3><ul>
<li><p>使用 <code>SELECT *</code> 进行查询;</p>
</li>
<li><p>创建了联合索引，但查询条件<strong>未准守最左匹配原则</strong>;</p>
</li>
<li><p>在<strong>索引列上进行计算</strong>、函数、类型转换等操作;</p>
</li>
<li><p>以 <code>%</code> 开头的 LIKE 查询比如 <code>like &#39;%abc&#39;</code>;</p>
</li>
<li><p>查询条件中使用 or，且 <strong>or 的前后条件中有一个列没有索引</strong>，涉及的索引都不会被使用到;</p>
</li>
<li><p><strong>对索引隐式类型转换</strong></p>
<blockquote>
<p>如果索引字段是<strong>字符串类型</strong>，但是在条件查询中，<strong>输入的参数是整型的话</strong>，你会在执行计划的结果发现这条语句会走全表扫描。</p>
</blockquote>
</li>
</ul>
<h3 id="如何分析语句是否走索引查询"><a href="#如何分析语句是否走索引查询" class="headerlink" title="如何分析语句是否走索引查询"></a>如何分析语句是否走索引查询</h3><p>可以使用 <code>EXPLAIN</code> 命令来分析 SQL 的 <strong>执行计划</strong> ，这样就知道语句是否命中索引了。执行计划是指一条 SQL 语句在经过 MySQL 查询优化器的优化会后，具体的执行方式。</p>
<p>mysql&gt; EXPLAIN SELECT <code>score</code>,<code>name</code> FROM <code>cus_order</code> ORDER BY <code>score</code> DESC;<br>+—-+————-+———–+————+——+—————+——+———+——+——–+———-+—————-+<br>| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra          |<br>+—-+————-+———–+————+——+—————+——+———+——+——–+———-+—————-+<br>|  1 | SIMPLE      | cus_order | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 997572 |   100.00 | Using filesort |<br>+—-+————-+———–+————+——+—————+——+———+——+——–+———-+—————-+<br>1 row in set, 1 warning (0.00 sec)</p>
<p><img   class="lazyload" data-original="https://blog.haohtml.com/wp-content/uploads/2010/06/mysql_explain.png" src=""  alt="关于MySQL explain 中的ID(推荐) | 学习笔记"></p>
<table>
<thead>
<tr>
<th><strong>列名</strong></th>
<th><strong>含义</strong></th>
</tr>
</thead>
<tbody><tr>
<td>id</td>
<td>SELECT 查询的序列标识符</td>
</tr>
<tr>
<td>select_type</td>
<td>SELECT 关键字对应的查询类型</td>
</tr>
<tr>
<td>table</td>
<td>用到的表名</td>
</tr>
<tr>
<td>partitions</td>
<td>匹配的分区，对于未分区的表，值为 NULL</td>
</tr>
<tr>
<td>type</td>
<td>表的访问方法（index ，ALL….）</td>
</tr>
<tr>
<td>possible_keys</td>
<td>可能用到的索引</td>
</tr>
<tr>
<td>key</td>
<td>实际用到的索引</td>
</tr>
<tr>
<td>key_len</td>
<td>所选索引的长度</td>
</tr>
<tr>
<td>ref</td>
<td>当使用索引等值查询时，与索引作比较的列或常量</td>
</tr>
<tr>
<td>rows</td>
<td>预计要读取的行数</td>
</tr>
<tr>
<td>Extra</td>
<td>附加信息</td>
</tr>
</tbody></table>
<h2 id="MySQL事务"><a href="#MySQL事务" class="headerlink" title="MySQL事务"></a>MySQL事务</h2><p><strong>事务是逻辑上的一组操作，要么都执行，要么都不执行。</strong></p>
<ul>
<li><strong>mysql开启事物</strong></li>
</ul>
<figure class="highlight clean"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># 开启一个事务</span><br><span class="line">START TRANSACTION;</span><br><span class="line"># 多条 SQL 语句</span><br><span class="line">SQL1,SQL2...</span><br><span class="line">## 提交事务</span><br><span class="line">COMMIT;</span><br></pre></td></tr></table></figure>

<h3 id="事物四大特性"><a href="#事物四大特性" class="headerlink" title="事物四大特性"></a>事物四大特性</h3><ol>
<li><strong>原子性</strong>（<code>Atomicity</code>） ： 事务是最小的执行单位，<strong>不允许分割</strong>。</li>
<li><strong>一致性</strong>（<code>Consistency</code>）： 执行事务前后，数据保持一致，例如转账业务中，无论事务是否成功，<strong>转账者和收款人的总额应该是不变的</strong>；</li>
<li><strong>隔离性</strong>（<code>Isolation</code>）： 并发访问数据库时，<strong>一个用户的事务不被其他事务所干扰</strong>，各并发事务之间数据库是独立的；</li>
<li><strong>持久性</strong>（<code>Durability</code>）： 一个事务被提交之后。<strong>它对数据库中数据的改变是持久的</strong>，即使数据库发生故障也不应该对其有任何影响。</li>
</ol>
<h3 id="InnoDB-引擎通过什么来保证事务的ACID"><a href="#InnoDB-引擎通过什么来保证事务的ACID" class="headerlink" title="InnoDB 引擎通过什么来保证事务的ACID"></a>InnoDB 引擎通过什么来保证事务的ACID</h3><ul>
<li>持久性：是通过 <strong>redo log （重做日志）</strong>来保证的；</li>
<li>原子性：是通过 <strong>undo log（回滚日志）</strong> 来保证的；</li>
<li>隔离性：是通过 <strong>MVCC（多版本并发控制）</strong> 或锁机制来保证的；</li>
<li>一致性：则是通过<strong>持久性+原子性+隔离性</strong>来保证；</li>
</ul>
<h3 id="并发事务带来了哪些问题"><a href="#并发事务带来了哪些问题" class="headerlink" title="并发事务带来了哪些问题"></a>并发事务带来了哪些问题</h3><ul>
<li><strong>脏读</strong>（Dirty read）： <strong>当前事务没有提交。这时另外一个事务读取了这个还未提交的数据</strong></li>
<li><strong>不可重复读</strong>（Unrepeatable read）： 指在一个事务内多次读同一数据。在这个事务还没有结束时，另一个事务也访问该数据。那么，在第一个事务中的两次读数据之间，由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况，因此称为不可重复读。</li>
</ul>
<p><img   class="lazyload" data-original="https://javaguide.cn/assets/concurrency-consistency-issues-unrepeatable-read.ff9186e1.png" src=""  alt="不可重复读"></p>
<ul>
<li><p><strong>幻读</strong>（Phantom read）：幻读与不可重复读类似。它发生在一个事务读取了几行数据，接着另一个并发事务插入了一些数据时。在随后的查询中，第一个事务就会发现多了一些原本不存在的记录，就好像发生了幻觉一样，所以称为幻读。</p>
<p><img   class="lazyload" data-original="https://javaguide.cn/assets/concurrency-consistency-issues-phantom-read.7cba7a85.png" src=""  alt="幻读"></p>
</li>
</ul>
<blockquote>
<p>这里的幻读和不可重复读很像，不可重复读是针对某一行数据来说，然鹅幻读是对整个表来说的</p>
<ul>
<li>不可重复读的重点是内容修改或者记录减少比如多次读取一条记录发现其中某些记录的值被修改；</li>
<li>幻读的重点在于记录新增比如多次执行同一条查询语句（DQL）时，发现查到的记录增加了。</li>
</ul>
</blockquote>
<h3 id="并发事务的控制方式有哪些"><a href="#并发事务的控制方式有哪些" class="headerlink" title="并发事务的控制方式有哪些"></a>并发事务的控制方式有哪些</h3><ul>
<li><p><strong>锁</strong>： MySQL 中主要是通过<strong>读写锁</strong> 来实现并发控制。</p>
<ul>
<li><p><strong>共享锁（S 锁）</strong> ：又称<strong>读锁</strong>，事务在读取记录的时候获取共享锁，允许多个事务同时获取。</p>
</li>
<li><p><strong>排他锁（X 锁）</strong> ：又称写锁&#x2F;独占锁，事务在修改记录的时候获取排他锁，不允许多个事务同时获取。如果一个记录已经被加了排他锁，那其他事务不能再对这条记录加任何类型的锁。</p>
<p><strong>读写锁可以做到读读并行，但是无法做到写读、写写并行。</strong></p>
<blockquote>
<p>行级锁的粒度更小，仅对相关的记录上锁即可（对一行或者多行记录加锁），所以对于并发写入操作来说， InnoDB 的性能更高。不论是表级锁还是行级锁，都存在共享锁（Share Lock，S 锁）和排他锁（Exclusive Lock，X 锁）这两类。</p>
</blockquote>
</li>
</ul>
</li>
<li><p><strong>MVCC</strong>： 可以看作是乐观控制的模式。</p>
</li>
</ul>
<h3 id="SQL-标准定义了四个隔离级别"><a href="#SQL-标准定义了四个隔离级别" class="headerlink" title="SQL 标准定义了四个隔离级别"></a>SQL 标准定义了四个隔离级别</h3><ul>
<li><strong>READ-UNCOMMITTED(读取未提交)</strong> ： 最低的隔离级别，允许读取尚未提交的数据变更，可能<strong>会导致脏读、幻读或不可重复读。</strong></li>
<li><strong>READ-COMMITTED(读取已提交)</strong> ： 允许读取并发事务已经提交的数据，可以<strong>阻止脏读</strong>，但是幻读或不可重复读仍有可能发生。</li>
<li><strong>REPEATABLE-READ(可重复读)</strong> ： 对同一字段的多次读取结果都是一致的，除非数据是被本身事务自己所修改，可以<strong>阻止脏读和不可重复读</strong>，但幻读仍有可能发生。</li>
<li><strong>SERIALIZABLE(可串行化)</strong> ： 最高的隔离级别，完全服从 ACID 的隔离级别。所有的事务依次逐个执行，这样事务之间就完全不可能产生干扰，也就是说，该级别可以<strong>防止脏读、不可重复读以及幻读</strong>。</li>
</ul>
<p><img   class="lazyload" data-original="https://gitee.com/yuan-wendong/picture-bed/raw/master/image-20230309162455302.png" src=""  alt="image-20230309162455302"></p>
<blockquote>
<p>mysql的隔离级别是根据MVCC实现的，默认是<strong>REPEATABLE-READ（可重读）</strong></p>
</blockquote>
<h2 id="MySQL锁"><a href="#MySQL锁" class="headerlink" title="MySQL锁"></a>MySQL锁</h2><h3 id="什么是-MVCC-以及实现"><a href="#什么是-MVCC-以及实现" class="headerlink" title="什么是 MVCC 以及实现"></a>什么是 MVCC 以及实现</h3><p> MVCC 的英文全称是 Multiversion Concurrency Control，中文意思是<strong>多版本并发控制</strong>，可以做到读写互相不阻塞，主要用于解决不可重复读和幻读问题时提高并发效率。</p>
<p>其原理是通过数据行的多个版本管理来实现数据库的并发控制，简单来说就是保存数据的历史版本。可以通过比较版本号决定数据是否显示出来。读取数据的时候不需要加锁可以保证事务的隔离效果。</p>
<h2 id="MySQL优化"><a href="#MySQL优化" class="headerlink" title="MySQL优化"></a>MySQL优化</h2><h3 id="尽量使用-TIMESTAMP，空间效率高于-DATETIME。"><a href="#尽量使用-TIMESTAMP，空间效率高于-DATETIME。" class="headerlink" title="尽量使用 TIMESTAMP，空间效率高于 DATETIME。"></a>尽量使用 TIMESTAMP，空间效率高于 DATETIME。</h3><h3 id="char-vs-varchar"><a href="#char-vs-varchar" class="headerlink" title="char vs varchar"></a>char vs varchar</h3><p>对于经常变更的数据来说，CHAR 比 VARCHAR更好，因为 CHAR 不容易产生内存碎片。</p>
<p>Char 范围是 0～255</p>
<p>效率来说基本是 Char &gt; Varchar &gt; Text，但是如果使用的是 Innodb 引擎的话，推荐使用 Varchar 代替 Char。</p>
<h3 id="MySQL-如何存储-IP-地址？"><a href="#MySQL-如何存储-IP-地址？" class="headerlink" title="MySQL 如何存储 IP 地址？"></a>MySQL 如何存储 IP 地址？</h3><p>可以将 IP 地址转换成整形数据存储，性能更好，占用空间也更小。</p>
<p>MySQL 提供了两个方法来处理 ip 地址</p>
<ul>
<li><code>INET_ATON()</code> ： 把 ip 转为无符号整型 (4-8 位)</li>
<li><code>INET_NTOA()</code> :把整型的 ip 转为地址</li>
</ul>
<p>插入数据前，先用 <code>INET_ATON()</code> 把 ip 地址转为整型，显示数据时，使用 <code>INET_NTOA()</code> 把整型的 ip 地址转为地址显示即可</p>
<h3 id="优化sql-…-where-status-x3D-1-order-by-create-time-asc"><a href="#优化sql-…-where-status-x3D-1-order-by-create-time-asc" class="headerlink" title="优化sql:  … where status &#x3D; 1 order by create_time asc"></a>优化sql:  … where status &#x3D; 1 order by create_time asc</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> <span class="keyword">order</span> <span class="keyword">where</span> status <span class="operator">=</span> <span class="number">1</span> <span class="keyword">order</span> <span class="keyword">by</span> create_time <span class="keyword">asc</span></span><br></pre></td></tr></table></figure>

<p>给 status 和 create_time 列建立一个联合索引,这样根据 status 筛选后的数据就是按照 create_time 排好序的，避免在文件排序，提高了查询效率。	</p>
<h2 id="MySQL日志"><a href="#MySQL日志" class="headerlink" title="MySQL日志"></a>MySQL日志</h2><ul>
<li><p><strong>错误日志</strong></p>
</li>
<li><p><strong>查询日志</strong></p>
</li>
<li><p><strong>慢查询日志</strong></p>
</li>
<li><p><strong>二进制日志</strong></p>
</li>
</ul>
<h3 id="错误日志"><a href="#错误日志" class="headerlink" title="错误日志"></a>错误日志</h3><blockquote>
<p> 错误日志记录mysqld启动、停止和服务器运行过程中发生的任何严重的错误信息。</p>
</blockquote>
<figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[mysqld]</span></span><br><span class="line"><span class="attr">log-error</span> = <span class="string">&quot;/home/chenyubo/www/logs/mysql.error.log&quot;</span></span><br></pre></td></tr></table></figure>

<p>若不指定文件名，默认文件名为hostname.err；若不指定目录，默认目录为DATADIR（数据目录）。</p>
<h3 id="查询日志"><a href="#查询日志" class="headerlink" title="查询日志"></a>查询日志</h3><p>查询日志记录了客户端执行的所有语句。二进制日志和查询不同的地方是，<strong>前者不包含查询数据的语句</strong>。</p>
<p>查询日志可以设置为保存在文件中或表中，可用log-output参数指定保存的位置：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">[mysqld]</span><br><span class="line"># 启用查询日志</span><br><span class="line">general-log = 1</span><br><span class="line"># 关闭查询日志</span><br><span class="line"># genera-log = 0</span><br><span class="line"># 查询日志路径</span><br><span class="line">general-log-file = &quot;/home/chenyubo/www/logs/mysql.general.log&quot;</span><br></pre></td></tr></table></figure>

<blockquote>
<p>这个一般不开，因为这个日志会记录DQL，ＤＭＬ等多种操作，很占内存</p>
</blockquote>
<h3 id="二级制日志"><a href="#二级制日志" class="headerlink" title="二级制日志"></a>二级制日志</h3><p>即binlog，记录所有的<strong>DDL</strong>语句和<strong>DML</strong>语句，但不包括查询语句。</p>
<p>二进制日志的格式有三种：基于语句的格式（<strong>STATEMENNT</strong>）、基于行的格式（<strong>ROW</strong>）和混合模式（<strong>MIXED</strong>）。</p>
<p>去配置…</p>
<blockquote>
<p>mysql的主从复制就是根据这个binlog</p>
</blockquote>
<p>删除二进制日志的方式</p>
<figure class="highlight crmsh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">mysql&gt; reset <span class="literal">master</span>;<span class="comment"># 删除所有的日志</span></span><br><span class="line">mysql&gt; purge <span class="keyword">master</span> <span class="title">logs</span> to &#x27;mysql-bin.<span class="number">000006</span>&#x27;;</span><br><span class="line">mysql&gt; purge <span class="keyword">master</span> <span class="title">logs</span> before &#x27;<span class="number">2020</span>-<span class="number">07</span>-<span class="number">10</span> <span class="number">12</span>:<span class="number">12</span>:<span class="number">12</span>&#x27;;<span class="comment"># 删除多少号之前的</span></span><br><span class="line">[mysqld] <span class="comment"># 配置过期时间</span></span><br><span class="line">expire_logs_days = <span class="number">3</span></span><br></pre></td></tr></table></figure>

<h3 id="慢查询日志"><a href="#慢查询日志" class="headerlink" title="慢查询日志"></a>慢查询日志</h3><p>慢查询日志记录所有执行时间<strong>超过long_query_time</strong>（单位为秒，精度可以到微妙）且记录数<strong>不小于min_examined_row_limit</strong>的所有SQL语句。</p>
<p>long_query_time默认为10s。但是<strong>管理语句和不使用索引查询的语句不会记录到慢查询日志</strong>。其中，管理语句包括：alter table，analyze talbe，check table，create table，create index，drop index，optimize table和repaire table</p>
<p>慢查询日志默认是关闭的，可用slow_query_log参数打开慢查询日志，并用slow_query_log_file指定日志路径。</p>
<figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[mysqld]</span></span><br><span class="line"><span class="comment"># 打开慢查询日志</span></span><br><span class="line"><span class="attr">slow_query_log</span> = <span class="number">1</span></span><br><span class="line"><span class="comment"># 关闭慢查询日志</span></span><br><span class="line"><span class="comment"># slow_query_log = 0</span></span><br><span class="line"> </span><br><span class="line"><span class="comment"># 设置慢查询阈值</span></span><br><span class="line"><span class="attr">long_query_time</span> = <span class="number">3</span></span><br><span class="line"> </span><br><span class="line"><span class="comment"># 设置慢查询日志路径</span></span><br><span class="line"><span class="attr">slow_query_log_file</span> = <span class="string">&quot;/home/chenyubo/www/logs/mysql.slow.log&quot;</span></span><br></pre></td></tr></table></figure>



<h2 id="sql区域"><a href="#sql区域" class="headerlink" title="sql区域"></a>sql区域</h2><ul>
<li><p>使用 MySQL 的 <code>REPLACE()</code> 函数来替换表中 name 列字段中的所有 “补油申请” 字符串为 “补油单”。下面是示例 SQL 查询语句：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">UPDATE</span> 表名</span><br><span class="line"><span class="keyword">SET</span> name <span class="operator">=</span> REPLACE(name, <span class="string">&#x27;补油申请&#x27;</span>, <span class="string">&#x27;补油单&#x27;</span>);</span><br></pre></td></tr></table></figure>
</li>
<li><p>查询当前的系统时间</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> sysdate()</span><br></pre></td></tr></table></figure>
</li>
<li><p>mybatis批量插入</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="operator">&lt;</span><span class="keyword">insert</span> id<span class="operator">=</span>&quot;batchUserPost&quot;<span class="operator">&gt;</span></span><br><span class="line">	<span class="keyword">insert</span> <span class="keyword">into</span> sys_user_post(user_id, post_id) <span class="keyword">values</span></span><br><span class="line">	<span class="operator">&lt;</span>foreach item<span class="operator">=</span>&quot;item&quot; index<span class="operator">=</span>&quot;index&quot; collection<span class="operator">=</span>&quot;list&quot; separator<span class="operator">=</span>&quot;,&quot;<span class="operator">&gt;</span></span><br><span class="line">		(#&#123;item.userId&#125;,#&#123;item.postId&#125;)</span><br><span class="line">	<span class="operator">&lt;</span><span class="operator">/</span>foreach<span class="operator">&gt;</span></span><br><span class="line"><span class="operator">&lt;</span><span class="operator">/</span><span class="keyword">insert</span><span class="operator">&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p><strong>分数排名sql</strong></p>
<blockquote>
<p>相同的分数，排名要相同，eg:1123456</p>
</blockquote>
<figure class="highlight stata"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">select <span class="keyword">score</span> , dese_rank() over(<span class="keyword">order</span> <span class="keyword">by</span> <span class="keyword">score</span> <span class="keyword">desc</span>) <span class="keyword">as</span> &#x27;rank&#x27;</span><br><span class="line"><span class="keyword">form</span> <span class="keyword">score</span> </span><br></pre></td></tr></table></figure></li>
</ul>

      </section>
      <section class="extra">
        
          <ul class="copyright">
  
    <li><strong>本文作者：</strong>东子</li>
    <li><strong>本文链接：</strong><a href="https://comebackearly.gitee.io/2022/06/03/Mysql/index.html" title="https:&#x2F;&#x2F;comebackearly.gitee.io&#x2F;2022&#x2F;06&#x2F;03&#x2F;Mysql&#x2F;index.html">https:&#x2F;&#x2F;comebackearly.gitee.io&#x2F;2022&#x2F;06&#x2F;03&#x2F;Mysql&#x2F;index.html</a></li>
    <li><strong>版权声明：</strong>本博客所有文章均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" title="BY-NC-SA" target="_blank" rel="noopener">BY-NC-SA</a> 许可协议，转载请注明出处！</li>
  
</ul>
        
        
        
        
  <nav class="nav">
    <a href="/2022/06/04/redis/"><i class="iconfont iconleft"></i>redis</a>
    <a href="/2022/06/02/java%E9%9B%86%E5%90%88%E6%80%BB%E7%BB%93/">java集合<i class="iconfont iconright"></i></a>
  </nav>

      </section>
      
        <section class="comments">
  
    <div class="btn" id="comments-btn">查看评论</div>
  
  
<div id="valine"></div>
<script defer src="//unpkg.com/valine/dist/Valine.min.js"></script>
<script>
  window.onload = function () {
    var loadValine = function () {
      new Valine({
        el: '#valine',
        app_id: "833C0IwLe9o8QE1pN25Mv59F-gzGzoHsz",
        app_key: "YLQZdn7egrZOmJnwr6YFEw0y",
        placeholder: "雁过留痕",
        avatar: "mp",
        pageSize: "10",
        lang: "zh-CN",
      });
    }
    if ( true ) {
      $("#comments-btn").on("click", function () {
        $(this).hide();
        loadValine();
      });
    } else {
      loadValine();
    }
  };
</script>

</section>
      
    </section>
  </div>
</article></div>
      <div class="col-xl-3">
        
          
  <aside class="toc-wrap">
    <h3 class="toc-title">文章目录：</h3>
    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#mysql%E6%80%BB%E7%BB%93"><span class="toc-text">mysql总结</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E7%A1%80%E6%9E%B6%E6%9E%84"><span class="toc-text">基础架构</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E4%B8%89%E5%A4%A7%E8%8C%83%E5%BC%8F"><span class="toc-text">什么是三大范式</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E8%8C%83%E5%BC%8F%E5%92%8C%E5%8F%8D%E8%8C%83%E5%BC%8F%EF%BC%8C%E4%BB%A5%E5%8F%8A%E5%90%84%E8%87%AA%E4%BC%98%E7%BC%BA%E7%82%B9"><span class="toc-text">什么是范式和反范式，以及各自优缺点</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E"><span class="toc-text">存储引擎</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#MySQL-%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E%E6%9E%B6%E6%9E%84"><span class="toc-text">MySQL 存储引擎架构</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#MyISM-%E5%92%8CInnoDB-%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB"><span class="toc-text">MyISM 和InnoDB 有什么区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#InnoDB-%E5%92%8C-MyISAM-%E9%83%BD%E6%94%AF%E6%8C%81-B-%E6%A0%91%E7%B4%A2%E5%BC%95%EF%BC%8C%E4%BD%86%E6%98%AF%E5%AE%83%E4%BB%AC%E6%95%B0%E6%8D%AE%E7%9A%84%E5%AD%98%E5%82%A8%E7%BB%93%E6%9E%84%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F%E4%B8%8D%E5%90%8C%E3%80%82"><span class="toc-text">InnoDB 和 MyISAM 都支持 B+ 树索引，但是它们数据的存储结构实现方式不同。</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B4%A2%E5%BC%95"><span class="toc-text">索引</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E7%B4%A2%E5%BC%95%EF%BC%9F"><span class="toc-text">什么是索引？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B4%A2%E5%BC%95%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9"><span class="toc-text">索引的优缺点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B4%A2%E5%BC%95%E5%BA%95%E5%B1%82%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84-%E4%B8%BA%E4%BB%80%E4%B9%88-MySQL-%E6%B2%A1%E6%9C%89%E4%BD%BF%E7%94%A8%E5%85%B6%E4%BD%9C%E4%B8%BA%E7%B4%A2%E5%BC%95%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%91%A2%EF%BC%9F"><span class="toc-text">索引底层数据结构,为什么 MySQL 没有使用其作为索引的数据结构呢？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#B%E6%A0%91%EF%BC%8CB-%E6%A0%91%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">B树，B+树的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B4%A2%E5%BC%95%E7%9A%84%E5%88%86%E7%B1%BB"><span class="toc-text">索引的分类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%BB%E9%94%AE%E7%B4%A2%E5%BC%95"><span class="toc-text">主键索引</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BA%8C%E7%BA%A7%E7%B4%A2%E5%BC%95-%E8%BE%85%E5%8A%A9%E7%B4%A2%E5%BC%95"><span class="toc-text">二级索引(辅助索引)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%81%9A%E7%B0%87%E7%B4%A2%E5%BC%95%E4%B8%8E%E9%9D%9E%E8%81%9A%E7%B0%87%E7%B4%A2%E5%BC%95%EF%BC%8C%E5%8F%8A%E5%85%B6%E4%BC%98%E7%BC%BA%E7%82%B9"><span class="toc-text">聚簇索引与非聚簇索引，及其优缺点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%9D%9E%E8%81%9A%E7%B0%87%E7%B4%A2%E5%BC%95%E4%B8%80%E5%AE%9A%E5%9B%9E%E8%A1%A8%E6%9F%A5%E8%AF%A2%E5%90%97"><span class="toc-text">非聚簇索引一定回表查询吗?</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9C%80%E5%B7%A6%E5%89%8D%E7%BC%80%E5%8C%B9%E9%85%8D%E5%8E%9F%E5%88%99"><span class="toc-text">最左前缀匹配原则</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B4%A2%E5%BC%95%E4%B8%8B%E6%8E%A8"><span class="toc-text">索引下推</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E7%B4%A2%E5%BC%95%E7%9A%84%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9%EF%BC%88%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99%EF%BC%89"><span class="toc-text">使用索引的注意事项（设计原则）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B4%A2%E5%BC%95%E5%A4%B1%E6%95%88%E7%9A%84%E5%8E%9F%E5%9B%A0"><span class="toc-text">索引失效的原因</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A6%82%E4%BD%95%E5%88%86%E6%9E%90%E8%AF%AD%E5%8F%A5%E6%98%AF%E5%90%A6%E8%B5%B0%E7%B4%A2%E5%BC%95%E6%9F%A5%E8%AF%A2"><span class="toc-text">如何分析语句是否走索引查询</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#MySQL%E4%BA%8B%E5%8A%A1"><span class="toc-text">MySQL事务</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BA%8B%E7%89%A9%E5%9B%9B%E5%A4%A7%E7%89%B9%E6%80%A7"><span class="toc-text">事物四大特性</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#InnoDB-%E5%BC%95%E6%93%8E%E9%80%9A%E8%BF%87%E4%BB%80%E4%B9%88%E6%9D%A5%E4%BF%9D%E8%AF%81%E4%BA%8B%E5%8A%A1%E7%9A%84ACID"><span class="toc-text">InnoDB 引擎通过什么来保证事务的ACID</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B9%B6%E5%8F%91%E4%BA%8B%E5%8A%A1%E5%B8%A6%E6%9D%A5%E4%BA%86%E5%93%AA%E4%BA%9B%E9%97%AE%E9%A2%98"><span class="toc-text">并发事务带来了哪些问题</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B9%B6%E5%8F%91%E4%BA%8B%E5%8A%A1%E7%9A%84%E6%8E%A7%E5%88%B6%E6%96%B9%E5%BC%8F%E6%9C%89%E5%93%AA%E4%BA%9B"><span class="toc-text">并发事务的控制方式有哪些</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#SQL-%E6%A0%87%E5%87%86%E5%AE%9A%E4%B9%89%E4%BA%86%E5%9B%9B%E4%B8%AA%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB"><span class="toc-text">SQL 标准定义了四个隔离级别</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#MySQL%E9%94%81"><span class="toc-text">MySQL锁</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF-MVCC-%E4%BB%A5%E5%8F%8A%E5%AE%9E%E7%8E%B0"><span class="toc-text">什么是 MVCC 以及实现</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#MySQL%E4%BC%98%E5%8C%96"><span class="toc-text">MySQL优化</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B0%BD%E9%87%8F%E4%BD%BF%E7%94%A8-TIMESTAMP%EF%BC%8C%E7%A9%BA%E9%97%B4%E6%95%88%E7%8E%87%E9%AB%98%E4%BA%8E-DATETIME%E3%80%82"><span class="toc-text">尽量使用 TIMESTAMP，空间效率高于 DATETIME。</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#char-vs-varchar"><span class="toc-text">char vs varchar</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#MySQL-%E5%A6%82%E4%BD%95%E5%AD%98%E5%82%A8-IP-%E5%9C%B0%E5%9D%80%EF%BC%9F"><span class="toc-text">MySQL 如何存储 IP 地址？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BC%98%E5%8C%96sql-%E2%80%A6-where-status-x3D-1-order-by-create-time-asc"><span class="toc-text">优化sql:  … where status &#x3D; 1 order by create_time asc</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#MySQL%E6%97%A5%E5%BF%97"><span class="toc-text">MySQL日志</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%94%99%E8%AF%AF%E6%97%A5%E5%BF%97"><span class="toc-text">错误日志</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9F%A5%E8%AF%A2%E6%97%A5%E5%BF%97"><span class="toc-text">查询日志</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BA%8C%E7%BA%A7%E5%88%B6%E6%97%A5%E5%BF%97"><span class="toc-text">二级制日志</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%85%A2%E6%9F%A5%E8%AF%A2%E6%97%A5%E5%BF%97"><span class="toc-text">慢查询日志</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#sql%E5%8C%BA%E5%9F%9F"><span class="toc-text">sql区域</span></a></li></ol></li></ol>
  </aside>

        
      </div>
    </div>
  </div>
</main>
  

<footer class="footer">
  <div class="footer-social"><a 
        href="tencent://message/?Menu=yes&uin=2911890696 "
        target="_blank"
        class="footer-social-item"
        onMouseOver="this.style.color= '#12B7F5'" 
        onMouseOut="this.style.color='#33333D'">
          <i class="iconfont  iconQQ "></i>
      </a><a 
        href="javascript:; "
        target="_blank"
        class="footer-social-item"
        onMouseOver="this.style.color= '#09BB07'" 
        onMouseOut="this.style.color='#33333D'">
          <i class="iconfont  iconwechat-fill "></i>
      </a><a 
        href="https://github.com/nuban "
        target="_blank"
        class="footer-social-item"
        onMouseOver="this.style.color= '#9f7be1'" 
        onMouseOut="this.style.color='#33333D'">
          <i class="iconfont  icongithub-fill "></i>
      </a></div>
  
    <div class="footer-copyright"><p>Powered by <a target="_blank" href="https://gitee.com/comebackearly">东子</a>  | 爷-青结~~</p></div>
  
  <link rel="stylesheet" href="/dist/APlayer.min.css">
  <div id="aplayer"></div>
  <script type="text/javascript" src="/dist/APlayer.min.js"></script>
  <script type="text/javascript" src="/dist/music.js"></script>
  
</footer>
  
      <div class="fab fab-plus">
    <i class="iconfont iconplus"></i>
  </div>
  
  
  
  <div class="fab fab-up">
    <i class="iconfont iconcaret-up"></i>
  </div>
  
  
  
    
<script src="/js/color-mode.js"></script>

  
  
</body>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>





  
<script src="https://cdn.bootcdn.net/ajax/libs/jquery.lazyload/1.9.1/jquery.lazyload.min.js"></script>




  
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js"></script>






  
<script src="https://cdn.bootcdn.net/ajax/libs/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>




<script src="/js/utils.js"></script>
<script src="/js/script.js"></script>







  <script>
    (function () {
      var bp = document.createElement('script');
      var curProtocol = window.location.protocol.split(':')[0];
      if (curProtocol === 'https') {
        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
      } else {
        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
      }
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(bp, s);
    })();
  </script>



  <script defer src='https://hm.baidu.com/hm.js?dda12e485d1b1d3113db8147f482111c'></script>











</html>